package eliauk.fun.flowabledemo.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import eliauk.fun.flowabledemo.service.BackTaskCmd;
import eliauk.fun.flowabledemo.service.FlowServiceFactory;
import eliauk.fun.flowabledemo.service.MyTaskService;
import eliauk.fun.flowabledemo.vo.CommentVo;
import eliauk.fun.flowabledemo.vo.Person;
import eliauk.fun.flowabledemo.vo.TaskVo;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.ManagementService;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.task.Comment;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.service.impl.persistence.entity.HistoricTaskInstanceEntityImpl;
import org.flowable.task.service.impl.persistence.entity.TaskEntityImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;


@Service
@Slf4j
public class MyTaskServiceImpl extends FlowServiceFactory implements MyTaskService {

    @Override
    public TaskVo convertToTaskVo(Task task) {
        TaskVo taskVo = new TaskVo();
        // 任务信息
        // 这里注意不能直接返回Task，Task 是个接口，需要转换为实现类
        TaskEntityImpl taskEntityImpl = (TaskEntityImpl) task;
        Object taskEntity = taskEntityImpl.getPersistentState();
        taskVo.setTask(taskEntity);

        // 任务 委托人 和 处理人 信息
        Person owner = new Person();
        owner.setUserId(1);
        owner.setUserName(task.getOwner());
        Person assignee = new Person();
        assignee.setUserId(2);
        assignee.setUserName(task.getAssignee());
        taskVo.setOwner(owner);
        taskVo.setAssignee(assignee);

        // 任务 审批信息
        List<String> commentTypes = Arrays.asList("taskResult", "taskComment", "taskResultMessage");
        List<CommentVo> commentVos = new ArrayList<>();
        for (String type : commentTypes) {
            List<Comment> comments = taskService.getTaskComments(task.getId(), type);
            for (Comment comment : comments) {
                CommentVo commentVo = new CommentVo(comment);
                commentVos.add(commentVo);
            }
        }
        return taskVo;
    }

    @Override
    public TaskVo convertToTaskVo(HistoricTaskInstance task) {
        TaskVo taskVo = new TaskVo();
        // 任务信息
        // 这里注意不能直接返回Task，Task 是个接口，需要转换为实现类
        HistoricTaskInstanceEntityImpl taskEntityImpl = (HistoricTaskInstanceEntityImpl) task;
        Object taskEntity = taskEntityImpl.getPersistentState();
        taskVo.setTask(taskEntity);

        // 任务 委托人 和 处理人 信息
        Person owner = new Person();
        owner.setUserId(1);
        owner.setUserName(task.getOwner());
        Person assignee = new Person();
        assignee.setUserId(2);
        assignee.setUserName(task.getAssignee());
        taskVo.setOwner(owner);
        taskVo.setAssignee(assignee);

        // 任务 审批信息
        List<String> commentTypes = Arrays.asList("taskResult", "taskComment", "taskResultMessage");
        List<CommentVo> commentVos = new ArrayList<>();
        for (String type : commentTypes) {
            List<Comment> comments = taskService.getTaskComments(task.getId(), type);
            for (Comment comment : comments) {
                CommentVo commentVo = new CommentVo(comment);
                commentVos.add(commentVo);
            }
        }
        taskVo.setCommentVo(commentVos);

        return taskVo;
    }

    @Override
    public TaskVo getTask(String taskId) {
        Assert.notNull(taskId, "任务ID不能为空");
        // 先查找处理中任务
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (task != null) {
            return convertToTaskVo(task);
        } else {
            // 任务已完成，查询历史任务
            HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
            Assert.notNull(historicTaskInstance, "任务不存在");
            return convertToTaskVo(historicTaskInstance);
        }
    }

    @Override
    public List<TaskVo> convertToTaskVo(List<Task> tasks) {
        return tasks.stream().map(this::convertToTaskVo).collect(Collectors.toList());
    }

    @Override
    public List<TaskVo> convertToTaskVos(List<HistoricTaskInstance> tasks) {
        return tasks.stream().map(this::convertToTaskVo).collect(Collectors.toList());
    }

    @Override
    public void terminateProcess(String processInstanceId, String reason) {
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                .processInstanceId(processInstanceId)
                .singleResult();
        String msg = "流程[" + processInstance.getName() + "]被终止，原因：" + reason;
        runtimeService.deleteProcessInstance(processInstanceId, msg);
    }

    public void terminateProcessByTaskId(String taskId, String reason) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                .processInstanceId(task.getProcessInstanceId())
                .singleResult();
        String msg = "流程[" + processInstance.getName() + "]被终止，原因：" + reason;
        runtimeService.deleteProcessInstance(task.getProcessInstanceId(), msg);
    }


    @Autowired
    private ManagementService managementService;
    //.....
    public void backTask(String taskId, String activityId) {
        String targetRealActivityId = managementService.executeCommand(new BackTaskCmd(runtimeService,
                taskId, activityId));
        log.info("TaskId:{},流程跳到到：{}", taskId, targetRealActivityId);
    }




    @Override
    public void rollbackTask(String taskId, String reason) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        Assert.notNull(task, "任务{}不存在", taskId);

        String proInstanceId = task.getProcessInstanceId();
        // 上一个任务节点
        HistoricTaskInstance previousTask = getPreviousNode(proInstanceId);
        Assert.notNull(previousTask, "流程[" + task.getName() + "]没有上一步任务");


        // 上一流程节点
        HistoricActivityInstance preNode = historyService.createHistoricActivityInstanceQuery()
                .activityId(previousTask.getTaskDefinitionKey())
                .orderByHistoricActivityInstanceStartTime()
                .desc().list().get(0);


        // 当前流程节点
        HistoricActivityInstance nowNode = historyService.createHistoricActivityInstanceQuery()
                .activityId(task.getTaskDefinitionKey())
                .orderByHistoricActivityInstanceStartTime()
                .desc().list().get(0);


        // 跳转到上一个节点
        runtimeService.createChangeActivityStateBuilder()
                .processInstanceId(proInstanceId)
                .moveActivityIdsToSingleActivityId(Arrays.asList(task.getTaskDefinitionKey()), previousTask.getTaskDefinitionKey())
                .changeState();


        // 删除当前节点 与上一节点的连线（不是删除线，而是两节点之间的连线状态）
        List<HistoricActivityInstance> hisActInsList = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(task.getProcessInstanceId())
                .startedAfter(preNode.getStartTime())
                .startedBefore(nowNode.getStartTime())
                .activityTypes(CollUtil.newHashSet("sequenceFlow"))
                .list(); // 查询所有历史节点信息
        

        runtimeService.createChangeActivityStateBuilder()
                .processInstanceId(proInstanceId)
                .changeState();

        //backTask(taskId, previousTask.getTaskDefinitionKey());
    }

    public HistoricTaskInstance getPreviousNode(String processInstanceId) {
        List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId)
                .finished()
                .orderByHistoricActivityInstanceEndTime().desc() // 按照时间倒序排序
                .list();
        for (HistoricActivityInstance historicActivityInstance : list) {
            if ("userTask".equals(historicActivityInstance.getActivityType())) {
                String taskId = historicActivityInstance.getTaskId();
                HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
                return historicTaskInstance;
            }
        }
        return null;
    }


}
